package com.fate.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fate.dao.ProdEsDao;
import com.fate.domain.Prod;
import com.fate.es.ProdEs;
import com.fate.service.ImportService;
import com.fate.service.ProdService;
import com.sun.scenario.effect.impl.prism.PrDrawable;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.security.core.parameters.P;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 功能描述: mysql的商品信息 导入es 里面去
 * 目的:因为mysql的访问量达不到要求 需要使用es 支持用户的正常访问
 * 场景:商品如何导入es
 * 实现:
 * 1.全量导入 mysql直接把商品全部导入es(发生在项目启动的时候(也可以自己触发),多线程批量分页导入
 * 2.增量导入
 * 3.快速导入
 *
 *
 * mysql--java --es
 */
@Service
@Slf4j
public class ImportServiceImpl implements ImportService, CommandLineRunner {

    @Autowired
    private ProdEsDao prodEsDao;

    @Autowired
    private ProdService prodService;

    /**
     * 起始时间
     */
    private Date t1;

    /**
     * 每页的条数
     */
    @Value("${esimport.size}")
    private Integer size;

    /**
     * 全量导入 项目将一起动 分批页多线程实现
     * 1.自定义分页
     * 1.1查询总条数
     * 2.2计算分页 int page = total %size ==0?total/size:((total/size)+1)
     * 2.3循环 fori
     * 3.查询数据库,prod prodes 对象转换一下
     * 4.导入es
     */
    @Override
    public void importAll() {
        //1.查询总条数
        Integer totalCount = prodService.getTotal(null,null);
        if (totalCount ==null ||totalCount==0){
            log.info("全量导入 商品数量为0");
            return;
        }
        //2.计算分页
      int page = totalCount%size ==  0?totalCount/size:((totalCount/size)+1);
        //3.循环使用mybatis循环mysql
        for(int i = 1;i<=page;i++){
            //查询mysql导入的方法
            importProdToEs(i,size,null,null);
        }
        log.info("导入完成");
        //记录一下t1 11.27
        t1 = new Date();

    }

    private void importProdToEs(int current, Integer size, Date t1, Date t2) {
        //1.组装分页对象 分页查询 需要发几个sql? limit 总条数 我这里分页查询 不需要总条数
       Page<Prod> page =  new Page<>(current,size,false);
       //2.查询prod表
        List<Prod> prodList = prodService.findProdPageByTime(page, t1, t2);
        //3.组装对象
        ArrayList<ProdEs> prodEsArrayList = new ArrayList<>(prodList.size() * 2);
        prodList.forEach(prod ->
        {
            ProdEs prodEs = new ProdEs();
            BeanUtil.copyProperties(prod,prodEs,true);
            prodEsArrayList.add(prodEs);
        });
        //导入es
        prodEsDao.saveAll(prodEsArrayList);
    }

    /**
     * 增量导入 商家上新
     * 定时任务
     * initialDelay:第一次执行的时间,fixedRate:第一次执行完以后,后面多久执行一次
     * 2分钟导入一次
     */
    @Override
    @Scheduled(initialDelay = 120 *1000,fixedRate = 120*1000)
    public void importUpdate() {
        log.info("增量导入开始");
        //每次执行增量导入 时间就往后推移
        Date t2 = new Date();
        //1.查询总条数
        Integer totalCount = prodService.getTotal(t1, t2);
        if (totalCount ==null ||totalCount ==0){
            //把时间窗口往后推移
            t1 = t2;
            log.info("增量导入 商品数量为0");
            return;
        }
        //2.计算分页
        int page = totalCount %size == 0?totalCount/size:((totalCount/size)+1);
        //3.循环使用mybatis 循环mysql
        for (int i = 1; i < page; i++) {
             //查询mysql 导入的方法
            importProdToEs(i,size,t1,t2);
        }
        log.info("导入完成");
        //把时间窗口往后推移
        t1 = t2;
    }

    @Override
    public void importQuick() {

    }


    @Override
    public void run(String... args) throws Exception {
        importAll();
    }
}
